package com.empress.uranus.zma.biz.machine.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.empress.uranus.zma.biz.machine.MCInvokeInboundHandlerBiz;
import com.empress.uranus.zma.biz.machine.adapter.MachineChargeAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineHeartBeatAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineHeartBeatIntervalAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineLockAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineMaintenceAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineOutpaperAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineRegisterAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineReviseAdapter;
import com.empress.uranus.zma.biz.machine.adapter.MachineShipmentAdapter;
import com.empress.uranus.zma.common.enums.WarehousePacketEnum;
import com.empress.uranus.zma.common.utils.PrinterUtil;
import com.empress.uranus.zma.domain.machine.dto.request.MachineChargeRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineHeartBeatIntervalRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineHeartBeatRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineLockRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineMaintenceRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineOutpaperRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineRegisterRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineReviseVitualRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.request.MachineShipmentRequestDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineChargeResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineHeartBeatIntervalResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineHeartBeatResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineLockResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineMaintenceResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineOutpaperResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineRegisterResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineReviseVitualResponseDTO;
import com.empress.uranus.zma.domain.machine.dto.response.MachineShipmentResponseDTO;
import com.empress.uranus.zma.domain.machine.packet.WarehousePacket;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

/**
 * 纸巾机服务器业务层处理数据输入实现类
 * 
 * @author taoxuejun
 * @date 2017-12-10
 */
@ChannelHandler.Sharable
@Service("mcinvokeInboundHandlerBiz")
public class MCInvokeInboundHandlerBizImpl extends MCInvokeInboundHandlerBiz {

	private static final Logger LOGGER = LoggerFactory.getLogger(MCInvokeInboundHandlerBizImpl.class);

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
	
		LOGGER.info("the napkin machine server invoke handler channel read: ctx :" + ctx);
		WarehousePacket warehousePacket = (WarehousePacket)msg;
		if(null == warehousePacket){
			LOGGER.info("reveive warehouse packet is null");
			return;
		}
		byte[] responseBytes = null;
		//调用业务端数据
		switch(WarehousePacketEnum.valueOf(warehousePacket.getFunctionCode())){
		 	//机器注册请求
		 	case REGISTER_REQUEST:
		 		MachineRegisterRequestDTO machineRegisterRequestDTO = MachineRegisterAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行机器注册请求服务端内部业务逻辑处理 do some work here");
		 		MachineRegisterResponseDTO machineRegisterResponseDTO = new MachineRegisterResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer registerReturnValue = 2;
		 		machineRegisterResponseDTO.setReturnValue(registerReturnValue);
		 		responseBytes = MachineRegisterAdapter.packetDtoToMachineBytes(machineRegisterResponseDTO, warehousePacket.getMessageId());
		 		break;
		 	//机器运营心跳请求
		 	case HEARTBEAT_REQUEST:
		 		MachineHeartBeatRequestDTO machineHeartBeatRequestDTO = MachineHeartBeatAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行机器运营心跳请求服务端内部业务逻辑处理 do some work here");
		 		MachineHeartBeatResponseDTO machineHeartBeatResponseDTO = new MachineHeartBeatResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer heartReturnValue = 2;
		 		machineHeartBeatResponseDTO.setReturnValue(heartReturnValue);
		 		responseBytes = MachineHeartBeatAdapter.packetDtoToMachineBytes(machineHeartBeatResponseDTO, warehousePacket.getMessageId());
		 		break;
		 	//机器运营心跳间隔设置请求
		 	case HEARTBEAT_INTERVAL_REQUEST:
		 		MachineHeartBeatIntervalRequestDTO machineHeartBeatIntervalRequestDTO = MachineHeartBeatIntervalAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行机器运营心跳间隔设置请求服务端内部业务逻辑处理 do some work here");
		 		MachineHeartBeatIntervalResponseDTO machineHeartBeatIntervalResponseDTO = new MachineHeartBeatIntervalResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer heartIntervalReturnValue = 2;
		 		machineHeartBeatIntervalResponseDTO.setReturnValue(heartIntervalReturnValue);
		 		responseBytes = MachineHeartBeatIntervalAdapter.packetDtoToMachineBytes(machineHeartBeatIntervalResponseDTO, warehousePacket.getMessageId());
		 		break;
		 	//出货请求
		 	case SHIPMENT_REQUEST:
		 		MachineShipmentRequestDTO machineShipmentRequestDTO = MachineShipmentAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行出货请求服务端内部业务逻辑处理 do some work here");
		 		MachineShipmentResponseDTO machineShipmentResponseDTO = new MachineShipmentResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer shipmentReturnValue = 2;
		 		machineShipmentResponseDTO.setReturnValue(shipmentReturnValue);
		 		responseBytes = MachineShipmentAdapter.packetDtoToMachineBytes(machineShipmentResponseDTO, warehousePacket.getMessageId());
		 		break;
		 	//充电请求
		 	case CHARGE_REQUEST:
		 		MachineChargeRequestDTO machineChargeRequestDTO = MachineChargeAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行充电请求服务端内部业务逻辑处理 do some work here");
		 		MachineChargeResponseDTO machineChargeResponseDTO = new MachineChargeResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer chargeReturnValue = 2;
		 		machineChargeResponseDTO.setReturnValue(chargeReturnValue);
		 		responseBytes = MachineChargeAdapter.packetDtoToMachineBytes(machineChargeResponseDTO, warehousePacket.getMessageId());
		 		break;	
		 	//维护请求
		 	case MAINTAIN_REQUEST:
		 		MachineMaintenceRequestDTO machineMaintenceRequestDTO = MachineMaintenceAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行充电请求服务端内部业务逻辑处理 do some work here");
		 		MachineMaintenceResponseDTO machineMaintenceResponseDTO = new MachineMaintenceResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer maintenceReturnValue = 2;
		 		machineMaintenceResponseDTO.setReturnValue(maintenceReturnValue);
		 		responseBytes = MachineMaintenceAdapter.packetDtoToMachineBytes(machineMaintenceResponseDTO, warehousePacket.getMessageId());
		 		break;	
		 	//电磁锁请求
		 	case ELECTROMAGNETIC_LOCK_REQUEST:
		 		MachineLockRequestDTO MachineLockRequestDTO = MachineLockAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行电磁锁请求服务端内部业务逻辑处理 do some work here");
		 		MachineLockResponseDTO machineLockResponseDTO = new MachineLockResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer lockReturnValue = 2;
		 		machineLockResponseDTO.setReturnValue(lockReturnValue);
		 		responseBytes = MachineLockAdapter.packetDtoToMachineBytes(machineLockResponseDTO, warehousePacket.getMessageId());
		 		break;
		 	//修改虚拟编号请求
		 	case REVISE_VIRTUAL_REQUEST:
		 		MachineReviseVitualRequestDTO MachineReviseVitualRequestDTO = MachineReviseAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行修改虚拟编号请求服务端内部业务逻辑处理 do some work here");
		 		MachineReviseVitualResponseDTO machineReviseVitualResponseDTO = new MachineReviseVitualResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer reviseReturnValue = 2;
		 		machineReviseVitualResponseDTO.setReturnValue(reviseReturnValue);
		 		responseBytes = MachineReviseAdapter.packetDtoToMachineBytes(machineReviseVitualResponseDTO, warehousePacket.getMessageId());
		 		break;	
		 	//出纸反馈请求
		 	case OUTPAPER_FEEDBACK_REQUEST:
		 		MachineOutpaperRequestDTO machineOutpaperRequestDTO = MachineOutpaperAdapter.machineBytesToPacketDTO(warehousePacket.getPayloadData());
		 		/**
		 		 * 在这里进行服务端内部业务逻辑处理
		 		 */
		 		LOGGER.info("这里进行出纸反馈请求服务端内部业务逻辑处理 do some work here");
		 		MachineOutpaperResponseDTO machineOutpaperResponseDTO = new MachineOutpaperResponseDTO();
		 		/**
		 		 * 经过业务处理后得到的返回值
		 		 *  mock
		 		 */
		 		Integer outpaperReturnValue = 2;
		 		machineOutpaperResponseDTO.setReturnValue(outpaperReturnValue);
		 		responseBytes = MachineOutpaperAdapter.packetDtoToMachineBytes(machineOutpaperResponseDTO, warehousePacket.getMessageId());
		 		break;	
		 	default:
		 		LOGGER.error("the napkin machine server channel function code={} off the range scope", warehousePacket.getFunctionCode());
		 		break;
		}
		//这里业务处理的结果转换成bytes数组返回给客户端
		if(responseBytes != null){
			ByteBuf invokeResponseBuf = ctx.alloc().buffer();
			invokeResponseBuf.writeBytes(responseBytes);
			ctx.write(invokeResponseBuf);
			LOGGER.info("此次调用服务端发送给纸巾机终端的响应数据是:{}", PrinterUtil.printHex(responseBytes, invokeResponseBuf.writerIndex()));
		}
	}
	
	@Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		LOGGER.info("the napkin machine server invoking handler channel has been inactive");
		ctx.close();
    }
	
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		
		LOGGER.info("the napkin machine server invoke handler channel has read completely");
		ctx.flush();
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		LOGGER.error("handling message in napkin server invoke handler caused exception", cause);
	}
}
